package com.lora.common;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.acooly.core.utils.Encodes;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lora.web.BaseUtil;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.acooly.core.common.web.AbstractJQueryEntityController;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Controller
@RequestMapping(value = "/common")
public class CommonController extends AbstractJQueryEntityController {

	protected void doExportExcelHeader(HttpServletRequest request, HttpServletResponse response) {
		String fileName = this.getExportFileName(request);
		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", "attachment");
		response.setHeader("Content-Disposition", "filename=\"" + Encodes.urlEncode(fileName) + ".xls\"");
	}

	/**
	 * 公用报表导出方法
	 * @param request
	 * @param response
	 * @param model
	 * @param exportTitles
	 * @param exportRows
	 * @param footerRows
	 * @param totalCol  表头的总列数
	 * @param totalRow  表头的总行数
	 */
	@SuppressWarnings({ "unchecked" })
	@RequestMapping(value = "report/commonExportReport")
	protected void commonExportReport(HttpServletRequest request, HttpServletResponse response, Model model, 
			String exportTitles, String exportRows, String footerRows, String totalCol, String totalRow) {
		doExportExcelHeader(request, response);
		WritableWorkbook workbook = null;
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workbook = Workbook.createWorkbook(out);
			WritableSheet sheet = workbook.createSheet(getExportFileName(request), 0);
			WritableCellFormat headerFormat = new WritableCellFormat(new WritableCellFormat());
			headerFormat.setAlignment(Alignment.CENTRE);
			headerFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
			headerFormat.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);
			headerFormat.setBackground(Colour.GREY_25_PERCENT);
			int rowIndex = 0;
			Map<String, Object> map = this.generateHead(sheet, headerFormat, exportTitles, Integer.parseInt(totalRow), Integer.parseInt(totalCol), rowIndex);
			WritableCellFormat bodyFormat = new WritableCellFormat(new WritableCellFormat());
			bodyFormat.setAlignment(Alignment.CENTRE);
			bodyFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
			bodyFormat.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);
			rowIndex = (int)map.get("rowIndex");
			List<String> fields = (ArrayList<String>) map.get("fields");
			JSONArray jsonArray = JSONObject.parseArray(exportRows);
			for(Object obj : jsonArray) {
				int i = 0;
				JSONObject jsonObj = JSONObject.parseObject(obj.toString());
				for(String field : fields) {
					sheet.addCell(new Label(i++, rowIndex, BaseUtil.isEmpty(jsonObj.get(field)) ? "" : jsonObj.get(field) + "", bodyFormat));
				}
				rowIndex++;
			}
			WritableCellFormat footerFormat = new WritableCellFormat(new WritableCellFormat());
			footerFormat.setAlignment(Alignment.CENTRE);
			footerFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
			footerFormat.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);
			footerFormat.setBackground(Colour.GREY_25_PERCENT);
			JSONArray footerJsonArray = JSONObject.parseArray(footerRows);
			for(Object obj : footerJsonArray) {
				int i = 0;
				JSONObject footerObj = JSONObject.parseObject(obj.toString());
				for(String field : fields) {
					Object object = BaseUtil.isEmpty(footerObj.get(field)) ? "" : footerObj.get(field);
					sheet.addCell(new Label(i++, rowIndex, object+"", footerFormat));
				}
				rowIndex++;
			}
			workbook.write();
			out.flush();
		} catch (Exception exc) {
			exc.printStackTrace();
			throw new RuntimeException("执行导出过程失败[" + exc.getMessage() + "]");
		} finally {
			try {
				workbook.close();
			} catch (Exception exc) {
				exc.printStackTrace();
			}
			IOUtils.closeQuietly(out);
		}
	}

	/**
	 * generate excel header
	 * @param sheet
	 * @param headerFormat
	 * @param exportTitles
	 * @param totalRow  total rows of header
	 * @param totalCol  total cols of header 
	 * @param rowIndex  header begin index
	 * @return
	 */
	private Map<String, Object> generateHead(WritableSheet sheet, WritableCellFormat headerFormat, String exportTitles, int totalRow, int totalCol, int rowIndex) {
		Map<String, Object> map = Maps.newHashMap();
		List<String> fields = Lists.newArrayList();
		String[] fieldArray = new String[totalCol];
		try {
			JSONArray jsonArray = JSONObject.parseArray(exportTitles);
			GenerateExcelHeadDto generate = new GenerateExcelHeadDto(totalRow, totalCol);
			for(Object obj : jsonArray) {
				JSONArray jsonArray1 = JSONObject.parseArray(obj.toString());
				int colIndex = 0;
				for(Object obj1 : jsonArray1) {
					colIndex = generate.getAvailblePositionCellByRow(rowIndex, colIndex);
					JSONObject jsonObj = JSONObject.parseObject(obj1.toString());
					String title = jsonObj.containsKey("title") ? jsonObj.getString("title") : "";
					String field = jsonObj.containsKey("field") ? jsonObj.getString("field") : "";
					int rowspan = jsonObj.containsKey("rowspan") ? Integer.parseInt(jsonObj.getString("rowspan")) : 1; 
					int colspan = jsonObj.containsKey("colspan") ? Integer.parseInt(jsonObj.getString("colspan")) : 1;
					sheet.addCell(new Label(colIndex, rowIndex, title, headerFormat));
					sheet.mergeCells(colIndex, rowIndex, colIndex + colspan - 1, rowIndex + rowspan - 1);
					for(int c = 0; c < colspan; c++) {
						for(int r = 0; r < rowspan; r++) {
							generate.usePosition(rowIndex + r, colIndex);
							if(StringUtils.isNotEmpty(field)) {
								fieldArray[colIndex] = field;
							}
						}
						colIndex++;
					}
				}
				rowIndex++;
			}
			for(String field : fieldArray) {
				fields.add(field);
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
		map.put("rowIndex", rowIndex);
		map.put("fields", fields);
		return map;
	}

}
